package com.hiv.service;

import java.util.*;
import java.util.stream.Collectors;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.RandomUtil;
import com.google.common.collect.Lists;
import com.hiv.common.PageInfo;
import com.hiv.common.param.SendSamplesParam;
import com.hiv.common.param.page.PageQueryBatchParam;
import com.hiv.common.utils.AssertUtil;
import com.hiv.mapper.RoleMapper;
import com.hiv.mapper.SamplingBoxMapper;
import com.hiv.mapper.SamplingBoxRecordMapper;
import com.hiv.mapper.SamplingRecordMapper;
import com.hiv.mapper.domain.Admin;
import com.hiv.mapper.domain.Role;
import com.hiv.mapper.domain.SamplingBox;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.hiv.mapper.BatchMapper;
import com.hiv.mapper.domain.Batch;
import org.springframework.transaction.annotation.Transactional;

/**
 * 批次Service业务层处理
 *
 * @author zhanghong
 * @date 2022-09-27
 */
@Service
public class BatchService {
    @Autowired
    private BatchMapper batchMapper;
    @Autowired
    private SamplingBoxMapper samplingBoxMapper;
    @Autowired
    private SamplingBoxRecordMapper samplingBoxRecordMapper;
    @Autowired
    private SamplingRecordMapper samplingRecordMapper;
    @Autowired
    private RoleMapper roleMapper;

    /**
     * 分页查询
     * @param param
     * @return
     */
    public PageInfo<Batch> pageQuery(Admin admin, PageQueryBatchParam param) {
        if (Objects.equals(admin.getType(), 3)) {//检验所
            param.setHospitalIdList(inspectionRelationHospital(admin.getHospitalId()));
            param.setHospitalId(null);
            param.setInspectionId(admin.getHospitalId());
            if (CollectionUtils.isEmpty(param.getHospitalIdList())) {
                return new PageInfo<>(param.getPageNum(), param.getPageSize(), Collections.emptyList(), 0);
            }
        }
        if (admin.getType() == null) {
            Integer countRole = roleMapper.countKgOrJyyByAdminId(admin.getId());
            AssertUtil.assertNotEqual(countRole, 0, "仅库管员/检验员操作");
            param.setHospitalIdList(inspectionRelationHospital(admin.getHospitalId()));
            param.setHospitalId(null);
            param.setInspectionId(admin.getHospitalId());
        }

        if (!Objects.equals(admin.getType(), 0)) {
            if (param.getHospitalId() == null && CollectionUtils.isEmpty(param.getHospitalIdList())) {
                return new PageInfo<>(param.getPageNum(), param.getPageSize(), Collections.emptyList(), 0);
            }
        }

        long count = batchMapper.pageCount(param);
        List<Batch> list = batchMapper.pageQuery(param, param.getPageSize(), param.fetchOffSet());
        list.forEach(item->buildInfo(item));
        return new PageInfo<>(param.getPageNum(), param.getPageSize(), list, count);
    }


    /**
     * 与检验所有关的医院集合
     *
     * @return
     */
    private List<Long> inspectionRelationHospital(Long inspectionId) {
        Set<Long> hospitalIdList = samplingBoxMapper.queryByInspectionId(inspectionId);
        return new ArrayList<>(hospitalIdList);
    }

    private void buildInfo(Batch item) {
        Integer boxNum = samplingBoxMapper.countBoxNumByBatchId(item.getId());
        Integer samplingNum =samplingRecordMapper.countSamplingNum(item.getId());
        item.setBoxNum(boxNum);
        item.setSamplingNum(samplingNum);
    }

    /**
     * 查询批次
     *
     * @param id 批次主键
     * @return 批次
     */
    public Batch getById(Long id) {
        return batchMapper.selectById(id);
    }

    /**
     * 查询批次列表
     *
     * @param batch 批次
     * @return 批次
     */
    public List<Batch> selectList(Batch batch) {
        return batchMapper.selectList(batch);
    }

    /**
     * 保存批次
     *
     * @param batch 批次
     * @return 结果
     */
    public Boolean save(Batch batch) {
        if (batch.getId() != null) {
            batchMapper.update(batch);
            return true;
        }
        batchMapper.insert(batch);
        return true;
    }

    /**
     * 批量删除批次
     *
     * @param ids 需要删除的批次主键
     * @return 结果
     */
    public Boolean deleteByIds(String ids) {
        batchMapper.deleteByIds(Convert.toStrArray(ids));
        return true;
    }

    /**
     * 寄样
     * @param param
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public Boolean sendSamples(Admin admin, SendSamplesParam param) {
        AssertUtil.assertNull(batchMapper.queryByExpress(param.getExpress()), "快递单号已存在");
        AssertUtil.assertNotNull(param.getExpress(), "快递单号为空");
        AssertUtil.assertNotEmpty(param.getSamplingBoxIds(), "寄样盒子为空");
        AssertUtil.assertNotNull(param.getInspectionId(), "检验所为空");

        Batch batch = new Batch();
        batch.setCode(RandomUtil.randomString(10));
        batch.setExpress(param.getExpress());
        batch.setExpressStatus(2);
        batch.setHospitalId(admin.getHospitalId());
        batch.setInspectionId(param.getInspectionId());
        batchMapper.insert(batch);

        for (Long boxId : param.getSamplingBoxIds()) {
            SamplingBox samplingBox = samplingBoxMapper.selectById(boxId);
            AssertUtil.assertNotNull(samplingBox, "非法的盒子id="+boxId);

            Integer samplingNum = samplingBoxRecordMapper.countByBoxId(boxId);
            samplingBox.setSamplingNum(samplingNum);
            samplingBox.setBatchId(batch.getId());
            samplingBox.setExpress(param.getExpress());
            samplingBox.setExpressStatus(2);
            samplingBox.setInspectionId(param.getInspectionId());
            samplingBoxMapper.update(samplingBox);
        }
        return true;
    }
}
